package com.lwl.mini.binding;

import com.lwl.mini.builder.annotation.MapperAnnotationBuilder;
import com.lwl.mini.session.Configuration;
import com.lwl.mini.session.DefaultSqlSession;
import com.lwl.mini.util.ResolverUtils;


import java.net.URL;
import java.util.*;

/**
 * @author lwl
 * @create 2022/4/12 9:55
 */
public class MapperRegistry {

    private final Configuration configuration;
    /**
     * key为类信息，value类信息的为代理工厂对象，存储的类中各种方法
     */
    private final Map<Class<?>,MapperProxyFactory<?>> knownMappers = new HashMap<>();

    public MapperRegistry(Configuration configuration){
        this.configuration = configuration;
    }

    public void addMappers(String packName)  {
        ResolverUtils<Class<?>> resolver = new ResolverUtils<>();
        resolver.find(packName);
        Set<Class<? extends Class<?>>> matches = resolver.getMatches();
        for(Class<?> mapperClass:matches){
            addMappers(mapperClass);
        }
    }

    /**
     * 将类信息装载入knownMapper集合中
     * key为类信息，value为相应的工厂
     * @param type 类信息
     */
    public <T> void addMappers(Class<T> type){
        if(type.isInterface()){
            if(knownMappers.containsKey(type)){
                //重复
                throw new BindingException("类信息<" +type+">已经加载过了.");
            }
            MapperProxyFactory proxyFactory = new MapperProxyFactory(type);
            knownMappers.put(type,proxyFactory);
            MapperAnnotationBuilder parser = new MapperAnnotationBuilder(proxyFactory,type);
            parser.parse();
            configuration.setKnownMappers(knownMappers);
        }
    }


    /**
     * @return 从knownMappers集合中获取出相应的类信息对应的代理工厂！
     */
    public <T> T getMapper(Class<T> type, DefaultSqlSession sqlSession) {
        final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
        if(mapperProxyFactory == null){
            throw new BindingException("该类未被注册进MapperRegistry中");
        }
        return mapperProxyFactory.newInstance(sqlSession);
    }
}
